package org.apaydin.beyazperde;

import org.apaydin.BaseFetcher;
import org.apaydin.CalendarUtils;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class BeyazperdeWeeklyFilmsFetcherImpl extends BaseFetcher implements BeyazperdeWeeklyFilmsFetcher {

    private final Week week;

    public BeyazperdeWeeklyFilmsFetcherImpl(Week week) {
        this.week = week;
    }

    @Override
    public List<Film> fetch() throws IOException, XPatherException {
        List<Film> films = new ArrayList<Film>();
        TagNode root = getRootTagNode(String.format(URL_PATTERN, week.toUrlString()));
        List<TagNode> filmNodes = evaluateXPath(root, "//div[@id='col_main']/div[@class='data_box']");
        for (TagNode filmNode : filmNodes) {
            Film film = new Film();

            String detailUrl = beyazperdeDetailUrl(filmNode);

            film.setTurkishName(turkishName(filmNode));
            film.setBeyazperdeDetailUrl(detailUrl);
            film.setPosterImage(posterImage(filmNode));

            List<TagNode> nodeList = evaluateXPath(filmNode, "//div[@class='content']//ul[@class='list_item_p2v']//li");
            film.setReleaseDate(releaseDate(nodeList));
            film.setDuration(duration(nodeList));
            film.setStars(stars(nodeList));
            film.setDirector(director(nodeList));

            TagNode detailRootNode = evaluateXPath(getRootTagNode(detailUrl), "//div[@id='col_main']", 0);
            film.setGenres(genres(detailRootNode));
            film.setDescription(description(detailRootNode));
            String orginalName = orginalName(detailRootNode);
            film.setOrginalName(orginalName == null ? film.getTurkishName() : orginalName);
            films.add(film);
        }
        return films;
    }

    private String turkishName(TagNode node) throws XPatherException {
        return evaluateXPath(node, "//div[@class='content']/div[1]//a", 0).getText().toString().trim();
    }

    private String orginalName(TagNode node) throws XPatherException {
        TagNode tagNode = evaluateXPath(node, "//div[@class='expendTable']/table//tr[1]", 0);
        if(evaluateXPath(tagNode, "/th",0).getText().indexOf("Orijinal adı") >= 0){
            return evaluateXPath(tagNode, "/td", 0).getText().toString().trim();
        }
        return null;
    }

    private String description(TagNode node) throws XPatherException {
        return evaluateXPath(node, "//p[@itemprop='description']", 0).getText().toString().trim();
    }

    private String posterImage(TagNode node) throws XPatherException {
        return evaluateXPath(node, "/div[@class='img_side_content']//img", 0).getAttributeByName("src");
    }

    private String director(List<TagNode> nodes) throws XPatherException {
        TagNode yonetmenNode = getTagNode(nodes, "Yönetmen");
        if(yonetmenNode != null){
            String[] ss = evaluateXPath(yonetmenNode, ".", 0).getText().toString().trim().split("\n\n");
            return ss[1];
        }
        return "";
    }

    private List<String> stars(List<TagNode> nodes) throws XPatherException {
        List<String> stars = new ArrayList<String>();
        TagNode oyuncularTagNode = getTagNode(nodes, "Oyuncular");
        if(oyuncularTagNode != null){
            String[] split = evaluateXPath(oyuncularTagNode, "//div", 0).getText().toString().trim().split(", ");
            stars.addAll(Arrays.asList(split));
        }
        return stars;
    }

    private List<String> genres(TagNode node) throws XPatherException {
        List<String> genres = new ArrayList<String>();
        TagNode turNode = getTagNode(evaluateXPath(node, "//div[@class='data_box']//div[@class='content']//ul[@class='list_item_p2v']/li"), "Tür");
        if(turNode != null){
            List<TagNode> tagNodes = evaluateXPath(turNode, "//span[@itemprop='genre']");
            for (TagNode n : tagNodes) {
                genres.add(n.getText().toString());
            }
        }
        return genres;
    }

    private TagNode getTagNode(List<TagNode> nodes, String text){
        for (TagNode node : nodes) {
            if(node.getText().indexOf(text) >= 0){
                return node;
            }
        }
        return null;
    }

    private String duration(List<TagNode> nodes) throws XPatherException {
        TagNode releaseDateNode = getTagNode(nodes, "Vizyon tarihi");
        if(releaseDateNode != null){
            String[] strings = evaluateXPath(releaseDateNode, "//div", 0).getText().toString().trim().split("\n");
            if(strings != null && strings.length > 1){
                return strings[1];
            }
        }
        return "";
    }

    private Date releaseDate(List<TagNode> nodes) throws XPatherException {
        TagNode releaseDateNode = getTagNode(nodes, "Vizyon tarihi");
        if(releaseDateNode != null){
            String[] strings = evaluateXPath(releaseDateNode, "//div", 0).getText().toString().trim().split("\n");
            return CalendarUtils.toCalendar(strings[0], "dd.MM.yyyy").getTime();
        }
        return null;
    }

    private String productionYear(TagNode node){
        return "";
    }

    private String beyazperdeDetailUrl(TagNode node) throws XPatherException {
        return BASE_URL + evaluateXPath(node, "//div[@class='content']/div[1]//a", 0).getAttributeByName("href");
    }


}
